﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Miris.HumanMilkAnalyser.DataModel;
using Miris.HumanMilkAnalyser.Service;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;
using Miris.HumanMilkAnalyser.WPF.ViewModel.TestItemViewModel;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel
{
    public class AllTestItemsViewModel : MyViewModelBase
    {
        public const string ShowAnalysisResultReportMessageToken = "AllTestResultsShowAnalysisResultReportMessage";
        public IEnumerable<DiagnosticMessageReference> DiagnosticMessageList { get; set; }
        public AnalysisResult CurrentAnalysisResult { get; set; }
        public DateTime TestDate { get; set; }

        /// <summary>
        /// Initializes a new instance of the AllTestItemsViewModel class.
        /// </summary>
        public AllTestItemsViewModel(IDataService dataService, MilkStage milkStage)
            : base(dataService)
        {
            InitializeEachSingleTestItem(milkStage);
        }

        /// <summary>
        /// The <see cref="SequenceNumber" /> property's name.
        /// </summary>
        public const string SequenceNumberPropertyName = "SequenceNumber";

        private int _sequenceNumber = 0;

        /// <summary>
        /// Sets and gets the SequenceNumber property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public int SequenceNumber
        {
            get
            {
                return _sequenceNumber;
            }

            set
            {
                if (_sequenceNumber == value)
                {
                    return;
                }

                RaisePropertyChanging(SequenceNumberPropertyName);
                _sequenceNumber = value;
                RaisePropertyChanged(SequenceNumberPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="IncludeBreastfeedingSignificance" /> property's name.
        /// </summary>
        public const string IncludeBreastfeedingSignificancePropertyName = "IncludeBreastfeedingSignificance";

        private bool _includeBreastfeedingSignificance = false;

        /// <summary>
        /// Sets and gets the IncludeBreastfeedingSignificance property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IncludeBreastfeedingSignificance
        {
            get
            {
                return _includeBreastfeedingSignificance;
            }

            set
            {
                if (_includeBreastfeedingSignificance == value)
                {
                    return;
                }

                RaisePropertyChanging(IncludeBreastfeedingSignificancePropertyName);
                _includeBreastfeedingSignificance = value;
                RaisePropertyChanged(IncludeBreastfeedingSignificancePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SampleNumber" /> property's name.
        /// </summary>
        public const string SampleNumberPropertyName = "SampleNumber";

        private string _sampleNumber = string.Empty;

        /// <summary>
        /// Sets and gets the SampleNumber property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string SampleNumber
        {
            get
            {
                return _sampleNumber;
            }

            set
            {
                if (_sampleNumber == value)
                {
                    return;
                }

                RaisePropertyChanging(SampleNumberPropertyName);
                _sampleNumber = value;
                RaisePropertyChanged(SampleNumberPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestDateDisplay" /> property's name.
        /// </summary>
        public const string TestDateDisplayPropertyName = "TestDateDisplay";

        private string _testDateDisplay = string.Empty;

        /// <summary>
        /// Sets and gets the TestDateDisplay property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestDateDisplay
        {
            get
            {
                return _testDateDisplay;
            }

            set
            {
                if (_testDateDisplay == value)
                {
                    return;
                }

                RaisePropertyChanging(TestDateDisplayPropertyName);
                _testDateDisplay = value;
                RaisePropertyChanged(TestDateDisplayPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SampleType" /> property's name.
        /// </summary>
        public const string SampleTypePropertyName = "SampleType";

        private string _sampleType = string.Empty;

        /// <summary>
        /// Sets and gets the SampleType property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string SampleType
        {
            get
            {
                return _sampleType;
            }

            set
            {
                if (_sampleType == value)
                {
                    return;
                }

                RaisePropertyChanging(SampleTypePropertyName);
                _sampleType = value;
                RaisePropertyChanged(SampleTypePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SampleStage" /> property's name.
        /// </summary>
        public const string SampleStagePropertyName = "SampleStage";

        private string _sampleStage = string.Empty;

        /// <summary>
        /// Sets and gets the SampleStage property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string SampleStage
        {
            get
            {
                return _sampleStage;
            }

            set
            {
                if (_sampleStage == value)
                {
                    return;
                }

                RaisePropertyChanging(SampleStagePropertyName);
                _sampleStage = value;
                RaisePropertyChanged(SampleStagePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="Fat" /> property's name.
        /// </summary>
        public const string FatPropertyName = "Fat";

        private TestItemFatViewModel _fat = null;

        /// <summary>
        /// Sets and gets the Fat property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemFatViewModel Fat
        {
            get
            {
                return _fat;
            }

            set
            {
                if (_fat == value)
                {
                    return;
                }

                RaisePropertyChanging(FatPropertyName);
                _fat = value;
                RaisePropertyChanged(FatPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="CrudeProtein" /> property's name.
        /// </summary>
        public const string CrudeProteinPropertyName = "CrudeProtein";

        private TestItemCrudeProteinViewModel _crudeProtein = null;

        /// <summary>
        /// Sets and gets the CrudeProtein property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemCrudeProteinViewModel CrudeProtein
        {
            get
            {
                return _crudeProtein;
            }

            set
            {
                if (_crudeProtein == value)
                {
                    return;
                }

                RaisePropertyChanging(CrudeProteinPropertyName);
                _crudeProtein = value;
                RaisePropertyChanged(CrudeProteinPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TrueProtein" /> property's name.
        /// </summary>
        public const string TrueProteinPropertyName = "TrueProtein";

        private TestItemTrueProteinViewModel _trueProtein = null;

        /// <summary>
        /// Sets and gets the TrueProtein property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemTrueProteinViewModel TrueProtein
        {
            get
            {
                return _trueProtein;
            }

            set
            {
                if (_trueProtein == value)
                {
                    return;
                }

                RaisePropertyChanging(TrueProteinPropertyName);
                _trueProtein = value;
                RaisePropertyChanged(TrueProteinPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="Carbohydrate" /> property's name.
        /// </summary>
        public const string CarbohydratePropertyName = "Carbohydrate";

        private TestItemCarbohydrateViewModel _carbohydrate = null;

        /// <summary>
        /// Sets and gets the Carbohydrate property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemCarbohydrateViewModel Carbohydrate
        {
            get
            {
                return _carbohydrate;
            }

            set
            {
                if (_carbohydrate == value)
                {
                    return;
                }

                RaisePropertyChanging(CarbohydratePropertyName);
                _carbohydrate = value;
                RaisePropertyChanged(CarbohydratePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TS" /> property's name.
        /// </summary>
        public const string TSPropertyName = "TS";

        private TestItemTSViewModel _ts = null;

        /// <summary>
        /// Sets and gets the TS property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemTSViewModel TS
        {
            get
            {
                return _ts;
            }

            set
            {
                if (_ts == value)
                {
                    return;
                }

                RaisePropertyChanging(TSPropertyName);
                _ts = value;
                RaisePropertyChanged(TSPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="Energy" /> property's name.
        /// </summary>
        public const string EnergyPropertyName = "Energy";

        private TestItemEnergyViewModel _energy = null;

        /// <summary>
        /// Sets and gets the Energy property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemEnergyViewModel Energy
        {
            get
            {
                return _energy;
            }

            set
            {
                if (_energy == value)
                {
                    return;
                }

                RaisePropertyChanging(EnergyPropertyName);
                _energy = value;
                RaisePropertyChanged(EnergyPropertyName);
            }
        }

        private RelayCommand _showAnalysisResultReportCommand;

        /// <summary>
        /// Gets the ShowAnalysisResultReportCommand.
        /// </summary>
        public RelayCommand ShowAnalysisResultReportCommand
        {
            get
            {
                return _showAnalysisResultReportCommand
                    ?? (_showAnalysisResultReportCommand = new RelayCommand(
                                          () =>
                                          {
                                              // Send to PatientDataSearchPage, request to show the selected test result report.
                                              Messenger.Default.Send<AllTestItemsViewModel>(this, AllTestItemsViewModel.ShowAnalysisResultReportMessageToken);
                                          }));
            }
        }

        /// <summary>
        /// Initialize each single test item property.
        /// </summary>
        /// <param name="milkStage">Selected MilkStage for current analysis sample.</param>
        private void InitializeEachSingleTestItem(MilkStage milkStage)
        {
            Fat = new TestItemFatViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
            CrudeProtein = new TestItemCrudeProteinViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
            TrueProtein = new TestItemTrueProteinViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
            Carbohydrate = new TestItemCarbohydrateViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
            TS = new TestItemTSViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
            Energy = new TestItemEnergyViewModel(null, SharedEntityStorage.AnalysisItemList, milkStage);
        }
    }
}
